import threading
class ServerRun(threading.Thread):
    def run(self):
        import socket
        self.setDaemon(True)

        serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #serversocket.bind((socket.gethostbyname(socket.gethostname()), 3340))
        serversocket.bind(("192.168.1.102", 3340))
        serversocket.listen(5)
        while 1:
            # wait for next client to connect
            connection, addr = serversocket.accept() # connection is a new socket
            while 1:
                data = connection.recv(1024) # receive up to 1K bytes
                if data:
                    DataToSend = BIFTServerAgent().receiveData(data)
                    while len(DataToSend) > 0:
                        if len(DataToSend) >= 1024:
                            connection.send(DataToSend[0:1023])
                            DataToSend = DataToSend[1023:len(DataToSend)]
                        else:
                            connection.send(DataToSend)
                            DataToSend = ''
                        
            connection.close()


class BIFTProtocol:
    ResultType = ''
    payload = None
    FileSize = 0
    
    def receiveData(self, obj):
        header = obj[0:obj.rfind('|||')]
        self.payload = obj.replace(obj[0:obj.rfind('|||')], "")
        self.payload = self.payload.replace("___!___endoffile", "")
        self.payload = self.payload.replace("|||", "")
        self.analyseHeader(header)
        print(self.ResultType)

    def analyseHeader(self, header):
        headerContents = header.split('|||')
        self.ResultType = headerContents[1]
        print(headerContents)

    def assemblePacket(self, payload, packetType, filePart, fileName):
        import os
        if packetType == 'command' or packetType == 'list':
            size = len(str(payload))
        else:
            size =  os.path.getsize(fileName)

        return str(size + len("|||" + str(packetType) + "|||" + "1" + "|||" + str(fileName) + "|||" + str(payload))) + "|||" + str(packetType) + "|||" + "1" + "|||" + str(fileName) + "|||" + str(payload) + "___!___endoffile"

class BIFTServerAgent(BIFTProtocol):
    currentFile = None
    
    def receiveData(self, obj):
        BIFTProtocol.receiveData(self, obj)
        result = None
        if self.ResultType == 'command':
            result = self.sintaxAnalyse(self.payload)
        elif self.ResultType == 'binary':
            result = self.fileAssemble(self.payload)
        else:
            result = self.returnData(self.payload)

        return BIFTProtocol.assemblePacket(self, result[0], result[1], result[2], result[3]);

    def sintaxAnalyse(self, payload):
        payloadResult = None
        fileName = ''
        if payload == "list":
            payloadResult = FileManager().listFiles()
            self.ResultType = 'list'
        elif payload.rfind('cd ') >= 0:
            payloadResult = FileManager().cd(payload.replace("cd ", ""))
            self.ResultType = 'command'
        elif payload.rfind('get ') >= 0:
            payloadResult = FileManager().getFile(payload.replace("get ", ""))
            fileName = payload.replace("get ", "")
            self.ResultType = 'binary'
        else:
            payloadResult = "Not a command"

        result = [payloadResult, self.ResultType, "", fileName] 
        return result;

    def fileAssemble(self, payload):
        print("Not implemented")

    def returnData(self, payload):
        print("Not implemented")



class FileManager:
    def listFiles(self):
        import os
        return os.listdir(os.getcwd())

    def cd(self, newDir):
        import os
        os.chdir(newDir)

    def getFile(self, filePath):
        file = open(filePath, "rb")
        return file.readlines()


class BIFTClientAgent(BIFTProtocol):
    currentFile = None
    
    def receiveData(self, obj):
        BIFTProtocol.receiveData(self, obj)
        if self.ResultType == 'list':
            print(self.payload)
        elif self.ResultType == 'binary':
            self.fileAssemble(self.payload)
        else:
            print("Not valid or not implemented yet.")

    def sintaxAnalyse(self, payload):
        print("Not implemented")

    def fileAssemble(self, payload):
        currentFile+= payload

    def returnData(self, payload):
        print("Not implemented")
    

    

ServerRun().run()
        
